<?php
/**
 * Transportation interface for FTP function
 * @author Nguyen Minh The
 * 
 */
interface ITransportation
{
	public function Send($srcPath, $srcFilename, $destPath="", $destFilename="", $transportTYPE = FTP::TransportTYPE_BINARY);
	public function Receive($srcPath, $srcFilename, $destPath="", $destFilename="", $transportTYPE = FTP::TransportTYPE_BINARY);
	public function Connect();
	public function Disconnect();
	public function Delete($srcFilename);
}

/**
 * Transportation class for FTP function
 * @author Nguyen Minh The
 * Created date: Mar-31 2008
 * Last updated date: Apr-03 2008
 */
class FTP implements ITransportation {
	const ProtocolTYPE_FTP = "FTP";
	const ProtocolTYPE_SFTP = "SFTP";
	const TransportTYPE_BINARY = FTP_BINARY;
	const TransportTYPE_ASCII = FTP_ASCII;
	const PassiveMODE_ON = true;
	const PassiveMODE_OFF = false;

	private  $errorMsg = "You don't have enough information for ftp action.";
	private $hostname;
	private $username;
	private $password;
	private $connID;
	private $srcPath;
	private $destPath;
	private $srcFile;
	private $destFile;	
	private $protocolTYPE;
	private $passiveMODE;
		
	/**
	 * This is init function for FTP class
	 *
	 * @param $hostname is The FTP server address.
	 * @param $username is username of the FTP connection.
	 * @param $password is password of the FTP connection.
	 * @param $protocolTYPE is transportation protocol, must be either FTP::ProtocolTYPE_FTP or FTP::ProtocolTYPE_SFTP value
	 * @param $passiveMODE is passive mode of the FTP conncection, must be either true or false value.
	 */
	function __construct($hostname, $username, $password, $protocolTYPE=FTP::ProtocolTYPE_FTP /* FTP::ProtocolTYPE_FTP | FTP::ProtocolTYPE_SFTP */, 
							$passiveMODE=FTP::PassiveMODE_ON /* FTP::PassiveMODE_ON | FTP::PassiveMODE_OFF */) {
		$this->hostname	= $hostname;
		$this->username	= $username;
		$this->password	= $password;	
		$this->protocolTYPE = $protocolTYPE;
		$this->passiveMODE = $passiveMODE;
	}	

	/**
	 * Function for getting error message when FTP function return false value.
	 * 
	 * @return Return a error message
	 */
	public function ErrorMessage() {return $this->errorMsg;}
		
	/**
	 * This function use for calling upload file from FTP object
	 *
	 * @param $srcPath is local directory contain file
	 * @param $srcFilename is local file name
	 * @param $destPath is remote directory contains file
	 * @param $destFilename is remote file name
	 * @param $transportTYPE is transfer mode, must be either FTP_ASCII or FTP_BINARY.
	 * @return return true if upload successful, return false if upload unsuccessful.
	 */
	public function Send($srcPath /* File's path need to upload*/, 
						 $srcFilename /* File's name need to upload*/, 
						 $destPath="" /* File's path need to save uploaded file*/, 
						 $destFilename="" /* File's name need to save uploaded file*/,
						 $transportTYPE = FTP::TransportTYPE_BINARY /* FTP::TransportTYPE_BINARY | FTP::TransportTYPE_ASCII */)
	{
		$this->srcPath = $srcPath;
		$this->srcFile = $srcFilename;
		$this->destPath = $destPath;
		$this->destFile = $destFilename;

		// upload the file
		$dest	= $this->destPath.$this->destFile;
		$src	= $this->srcPath.$this->srcFile;
		if (trim($src)=="") 
		{
			$this->raiseError("No source file for uploading.");
			return false;
		}
		if (trim($destFilename) == "") $dest = $dest.$this->srcFile;

		if (!$this->connID) {
			$this->raiseError("Please connect to server before running upload file.");
			return false;
		}
		$upload = ftp_put($this->connID, $dest, $src, $transportTYPE); 
		//if (!ftp_rename($this->connID, "/ps_xml/xmltestDown.xml", "/ps_xml/gds_20080402_120658_itemsku.xml")) echo "Long name.";

		// check upload status
		if (!$upload)
		{
			$this->raiseError("There was a problem while uploading $src.");
			return false;
		}
		return true;
	}
	
	/**
	 * This function use for downloading file from FTP object
	 *
	 * @param $remotePath is remote directory contains file
	 * @param $remoteFilename is remote file name
	 * @param $localPath is local directory contain file
	 * @param $localFilename is local file name
	 * @param $transportTYPE is transfer mode, must be either FTP_ASCII or FTP_BINARY.
	 * @return return true if download successful, return false if download unsuccessful.
	 */
	public function Receive($remotePath /* File's path need to download*/, 
						 $remoteFilename /* File's name need to download*/, 
						 $localPath="" /* File's path need to save downloaded file*/, 
						 $localFilename="" /* File's name need to save downloaded file*/,
						 $transportTYPE = FTP::TransportTYPE_BINARY /* FTP::TransportTYPE_BINARY | FTP::TransportTYPE_ASCII */)
	{
		$this->srcPath = $remotePath;
		$this->srcFile = $remoteFilename;
		$this->destPath = $localPath;
		$this->destFile = $localFilename;

		// download the file
		$dest	= $this->destPath.$this->destFile;
		$src	= $this->srcPath.$this->srcFile;
		if (trim($src)=="") 
		{
			$this->raiseError("No source file for uploading.");
			return false;
		}
		if (trim($this->destFile) == "") $dest = $dest.$this->srcFile;

		if (!$this->connID) {
			$this->raiseError("Please connect to server before running download file.");
			return false;
		}
		$download = ftp_get($this->connID, $dest, $src, $transportTYPE); 

		// check download status
		if (!$download)
		{
			$this->raiseError("There was a problem while downloading $src.");
			return false;
		}

		return true;
	}
	
	
	/**
	 * This function use for calling File Deleting command of FTP object
	 *
	 * @return return true if delete successful, return false if delete unsuccessful.
	 */
	public function Delete($srcFilename) 
	{
		if ($srcFilename==null || trim($srcFilename==""))
		{
			$this->raiseError("Filename is empry, can't delete.");
			return false;
		} else if (!$this->connID) {
			$this->raiseError("Please connect to server before running delete file.");
			return false;
		} else if (!ftp_delete($this->connID, $srcFilename)) {
			$this->raiseError("Can't delete \"$srcFilename\".");
			return false;
		}
		return true;
	}

	
	/**
	 * This function use for calling Connection command of FTP object
	 *
	 * @return return true if connect successful, return false if connect unsuccessful.
	 */
	public function Connect() 
	{
		$this->errorMsg = "";
		if (trim($this->hostname)=="") {
			$this->raiseError("Please set hostname value to ftp!");
			return false;
		}
		if ($this->protocolTYPE==FTP::ProtocolTYPE_FTP) {
			if(!function_exists('ftp_connect')) {
				$this->raiseError("'ftp_connect()' function not found!");
				return false;
			}
			$this->connID = ftp_connect($this->hostname);
		}
		else if ($this->protocolTYPE==FTP::ProtocolTYPE_SFTP) {
			if(!function_exists('ftp_ssl_connect')) {
				$this->raiseError("'ftp_ssl_connect()' function not found!");
				return false;
			}
			$this->connID = ftp_ssl_connect($this->hostname);
		}
		else
			$this->connID = ftp_connect($this->hostname);

		if (!$this->connID) {
			$this->raiseError("Couldn't connect to ".$this->hostname." with FTP's information you applied");
			return false;
		}
		
				return $this->login();
	}

	/**
	 * This function use for calling Disconnection command of FTP object.
	 *
	 */
	public function Disconnect() {
		if ($this->connID) 
			ftp_close($this->connID); 
	}

	/**
	 * This private function use for implementing ftp login
	 *
	 * @return return true if login successful, return false if login unsuccessful.
	 */
	private function login() 
	{
		$this->errorMsg = "";
		if (!ftp_login($this->connID, $this->username, $this->password)) 
			$this->raiseError("Couldn't connect to ".$this->hostname." with FTP's information you applied.");
		
		ftp_pasv($this->connID, $this->passiveMODE);

		return ($this->errorMsg=="");
	}

	/**
	 * This is private function use for raise an error message of FTP object.
	 *
	 * @param $msg is a message need to raise.
	 */
	private function raiseError($msg) 
	{
		$this->errorMsg = $msg;
	}

}
?>